﻿using System;
using System.IO;
using Catel.Data;
using Catel.MVVM.Services;
using DevExpress.Xpo;
using DevExpress.Xpo.DB;

namespace LprMiddleWare.ViewModels
{
    using Catel.MVVM;

    /// <summary>
    /// UserControl view model.
    /// </summary>
    public class SettingsViewModel : ViewModelBase
    {
        private IMessageService _messageService;
        private IPleaseWaitService _pleaseWaitService;

        /// <summary>
        /// Initializes a new instance of the <see cref="SettingsViewModel"/> class.
        /// </summary>
        public SettingsViewModel()
        {
            _messageService = GetService<IMessageService>();
            _pleaseWaitService = GetService<IPleaseWaitService>();

            RemoveHostCommand = new Command(OnRemoveHostExecute, OnRemoveHostCanExecute);
            AddHostCommand = new Command(OnAddHostCommandExecute);
            TestDatabaseConnCommand =
                new Command(OnTestDatabaseConnCommandExecute,
                OnTestDatabaseConnCommandCanExecute);

            // TODO: Move code below to constructor
            TestRemoteDatabaseConnCommand =
                new Command(OnTestRemoteDatabaseConnCommandExecute,
                    OnTestRemoteDatabaseConnCommandCanExecute);
            // TODO: Move code above to constructor


            // TODO: Move code below to constructor
            TestUploadWebService = new Command(OnTestUploadWebServiceExecute);
            // TODO: Move code above to constructor

        }

        /// <summary>
        /// Gets the title of the view model.
        /// </summary>
        /// <value>The title.</value>
        public override string Title { get { return "选项设置"; } }

        // TODO: Register models with the vmpropmodel codesnippet
        // TODO: Register view model properties with the vmprop or vmpropviewmodeltomodel codesnippets
        // TODO: Register commands with the vmcommand or vmcommandwithcanexecute codesnippets
        /// <summary>
        /// Gets the TestUploadWebService command.
        /// </summary>
        public Command TestUploadWebService { get; private set; }



        /// <summary>
        /// Method to invoke when the TestUploadWebService command is executed.
        /// </summary>
        private async void OnTestUploadWebServiceExecute()
        {
            var msg = string.Empty;
            var test = new TestUploadWebservice();

            _pleaseWaitService.Show("请稍候...");

            try
            {
                msg = await test.TestUploadServiceAsync(Settings.WeiZhangDataUrl, Settings.UploadKey, Settings.UploadDwbm, Settings.UploadLry);
            }
            catch (Exception ex)
            {
                msg = ex.Message;
            }

            _pleaseWaitService.Hide();
            _messageService.Show(msg);
        }
        /// <summary>
        /// Gets the OnTestRemoteDbConnection command.
        /// </summary>
        public Command TestRemoteDatabaseConnCommand { get; private set; }


        /// <summary>
        /// Gets the TestDatabaseConnCommand command.
        /// </summary>
        public Command TestDatabaseConnCommand { get; private set; }


        /// <summary>
        /// Method to check whether the TestDatabaseConnCommand command can be executed.
        /// </summary>
        /// <returns><c>true</c> if the command can be executed; otherwise <c>false</c></returns>
        private bool OnTestDatabaseConnCommandCanExecute()
        {
            return OnTestDatabaseConnCommandCanExecuteInternal(true);


        }

        private bool OnTestRemoteDatabaseConnCommandCanExecute()
        {

            return OnTestDatabaseConnCommandCanExecuteInternal(false);
        }

        private bool OnTestDatabaseConnCommandCanExecuteInternal(bool isLocal)
        {

            var result = !string.IsNullOrEmpty(isLocal ? Settings.DbServer : Settings.RemoteDbServer)
                && !string.IsNullOrEmpty(isLocal ? Settings.DbUserName : Settings.RemoteDbUserName)
                && !string.IsNullOrEmpty(isLocal ? Settings.DbPassWord : Settings.RemoteDbPassWord);
            return result;
        }

        /// <summary>
        /// Method to invoke when the TestDatabaseConnCommand command is executed.
        /// </summary>
        private async void OnTestDatabaseConnCommandExecute()
        {
            OnTestDatabaseConnCommandExecuteInternal(true);
        }

        private async void OnTestRemoteDatabaseConnCommandExecute()
        {
            OnTestDatabaseConnCommandExecuteInternal(false);
        }


        private async void OnTestDatabaseConnCommandExecuteInternal(bool isLocal)
        {

            _pleaseWaitService.Show("测试数据库连接...");

            var result = await System.Threading.Tasks.TaskEx.Run(() =>
            {
                try
                {
                   var dataLayer =  Helper.ConnectToOracleDb(
                        isLocal ? Settings.DbServer : Settings.RemoteDbServer,
                        isLocal ? Settings.DbUserName : Settings.RemoteDbUserName,
                        isLocal ? Settings.DbPassWord : Settings.RemoteDbPassWord
                        );

                   dataLayer.Dispose();
                    return null;
                }
                catch (Exception ex)
                {
                    return ex;
                }

            });

            _pleaseWaitService.Hide();
            if (result == null)
            {
                _messageService.ShowInformation("测试成功");
            }
            else
            {
                _messageService.ShowError("测试失败\r\n\r\n" + result.Message);
            }
        }




        /// <summary>
        /// Gets the AddHostCommand command.
        /// </summary>
        public Command AddHostCommand { get; private set; }



        /// <summary>
        /// Method to invoke when the AddHostCommand command is executed.
        /// </summary>
        private void OnAddHostCommandExecute()
        {
            // TODO: Handle command logic here
            var h = new IpPort();
            Settings.Hosts.Add(h);
            SelectedHost = h;
        }

        /// <summary>
        /// Gets the RemoveHost command.
        /// </summary>
        public Command RemoveHostCommand { get; private set; }



        /// <summary>
        /// Method to check whether the RemoveHost command can be executed.
        /// </summary>
        /// <returns><c>true</c> if the command can be executed; otherwise <c>false</c></returns>
        private bool OnRemoveHostCanExecute()
        {
            return SelectedHost != null;
        }

        /// <summary>
        /// Method to invoke when the RemoveHost command is executed.
        /// </summary>
        private void OnRemoveHostExecute()
        {
            Settings.Hosts.Remove(SelectedHost);
        }

        /// <summary>
        /// selected ip port.
        /// </summary>
        public IpPort SelectedHost
        {
            get { return GetValue<IpPort>(SelectedHostProperty); }
            set { SetValue(SelectedHostProperty, value); }
        }

        /// <summary>
        /// Register the SelectedHost property so it is known in the class.
        /// </summary>
        public static readonly PropertyData SelectedHostProperty = RegisterProperty("SelectedHost", typeof(IpPort));

        /// <summary>
        /// Settings.
        /// </summary>
        [Model]
        public Settings Settings
        {
            get { return GetValue<Settings>(SettingsProperty); }
            set { SetValue(SettingsProperty, value); }
        }

        /// <summary>
        /// Register the Settings property so it is known in the class.
        /// </summary>
        public static readonly PropertyData SettingsProperty = RegisterProperty("Settings", typeof(Settings), new Settings());


        protected override void Initialize()
        {
            try
            {
                Settings = Settings.LoadDefault();
            }
            catch (Exception)
            {
                _messageService.ShowError("读取配置出错，配置已经恢复为缺省值");
            }

            base.Initialize();
        }

        protected override bool Save()
        {
            Settings.Validate(true);
            if (Settings.HasErrors)
            {
                _messageService.ShowError("系统设置有错误，请先纠正错误。");
                return false;
            }

            Settings.Save();

            _messageService.ShowInformation("设置已经保存，重新启动后，设置才会生效。");

            return base.Save();
        }
    }
}
